package com.spring.batch.fieldmapper;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Service;

import datamigartion.Column;

@Service
public class CompositeFieldMapper implements FieldMapper<Map<String, Object>, Map<String, Object>>,
		BeanFactoryPostProcessor {
	Log logger = LogFactory.getLog(this.getClass());
	private final Map<String, FieldMapper<Object,Object>> fieldMapperMap = new ConcurrentHashMap<String, FieldMapper<Object,Object>>();
	private List<Column> cloumnsMapping;
	
	@Override
	public Map<String, Object> mapping(Map<String, Object> rows) {
		for (Column column : cloumnsMapping) {
			String fieldMapperIDs = column.getFieldMapper();
			if (StringUtils.isNotEmpty(fieldMapperIDs)) {
				if (logger.isInfoEnabled()) {
					logger.info("table {" + column.getSource() + "}" + "cloumn {" + column.getSource() + "}" + "mapper{"
							+ fieldMapperIDs + "}");
				}
				for (String fieldMapperID : fieldMapperIDs.split(",")) {
					String columnName = column.getSource();
					FieldMapper<Object,Object> fileMapper = fieldMapperMap.get(fieldMapperID);
					Object columnValue = rows.get(columnName);
					Object mappingValue = fileMapper.mapping(columnValue);
					logger.info("cloumn name {" + columnName +"}" +" before value [" + columnValue +"]" + " change value[" + mappingValue +"]");
					rows.put(columnName, mappingValue);
				}
			}
		}
		return rows;
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		Map<String, FieldMapper> fieldMapperBeans = beanFactory.getBeansOfType(FieldMapper.class);
		if (logger.isDebugEnabled()) {
			logger.debug("CompositeFieldMapper size is " + fieldMapperMap.size());
		}
		for (Map.Entry<String, FieldMapper> entry : fieldMapperBeans.entrySet()) {
			if (!(entry.getValue() instanceof CompositeFieldMapper)) {
				String fieldMapperID = entry.getKey().substring(0, entry.getKey().length() - 6);
				fieldMapperMap.put(fieldMapperID, entry.getValue());
			}
		}
	}

	public void setCloumnsMapping(List<Column> cloumnsMapping) {
		this.cloumnsMapping = cloumnsMapping;
	}

}
